﻿#include "wswitchnode.h"
#include "wnodemanager.h"
#include "wxpolygonex.h"
#include "../common.h"
#include "../scriptmanager.h"
#include <wx/strconv.h>

WSwitchNode::WSwitchNode()
    : m_SwitchState(SwitchState::NOINIT)
{
    this->setNodeType(NODE_SWITCH);
}

WSwitchNode::WSwitchNode(wxString pname)
    : WBaseNode(pname),
      m_SwitchState(SwitchState::NOINIT)
{
    this->setNodeType(NODE_SWITCH);

    /// 注册结点到lua中
    ScriptManager::getSingleton().registerBaseNodetoLua("S_",this);

    m_onMouseEventString = wxString(wxT("onMouseEvent_S_")+this->getName());
    m_onUpdateEventString = wxString(wxT("update_S_")+this->getName());
    m_onDrawEventString = wxString(wxT("draw_S_")+this->getName());
}

WSwitchNode::~WSwitchNode()
{

}

/// 建立脚本文件
bool WSwitchNode::createScriptFile(void)
{
    // 目标文件
    const wxString decScriptFile = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+
                             wxString::Format("/resources/scripts/nodes/%s.lua",this->getName());

    if(wxFileExists(decScriptFile))
        return false;

    const wxString decScriptDir = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+
            "/resources/scripts/nodes";

    // 检测指定目录是否存在，不存在创建目录
    if(!wxDir::Exists(decScriptDir))
    {
        if (!wxFileName::Mkdir(decScriptDir, 0755, wxPATH_MKDIR_FULL))
            return false;
    }

    wxString tmpScriptContent = wxString(wxT("--结点更新\n"
                                         "function update_%s()\n"
                                         "\n"
                                         "end\n"
                                         "\n"
                                         "--[[鼠标事件处理]]--\n"
                                         "function onMouseEvent_%s(event)\n"
                                         "\n"
                                         "end\n"
                                         "\n"
                                         "--绘制结点\n"
                                         "function draw_%s(painter)\n"
                                         "   local p%s = WSwitchNode.castFromBase(%s);\n"
                                         "   if p%s == nil then return end\n"
                                         "\n"
                                         "end"));
    tmpScriptContent.Replace("%s","S_"+this->getName());


    wxFile decfile;
    if (!decfile.Create(decScriptFile, true))
        return false;

    wxCSConv conv("UTF-8");

    if (!decfile.Write(tmpScriptContent,conv)) {
        decfile.Close();
        return false;
    }

    decfile.Close();

    return true;
}

/// 设置结点管理器
void WSwitchNode::setNodeManager(WNodeManager *pNodeManager)
{
    WBaseNode::setNodeManager(pNodeManager);

    // 挂接道岔改变信号槽
    sig_switch_change.connect(pNodeManager,&WNodeManager::slot_processSwitchChangeToSect);
}

/// 设置道岔状态
void WSwitchNode::setSwitchState(int state)
{
    bool isSendSignal = false;

    if(m_SwitchState != (SwitchState)state)
        isSendSignal = true;

    m_SwitchState = (SwitchState)state;

    if(isSendSignal) sig_switch_change.emitt("");
}

/// 初始道岔状态
bool WSwitchNode::initSwitchState(int state,wxString startpos,wxString endpos)
{
    if(startpos == "" || endpos == "")
        return false;

    tagMountPoint* pstartpos = this->getMountPointByName(startpos);
    tagMountPoint* pendpos = this->getMountPointByName(endpos);

    // 挂接点找不到或者方向一致都不行
    if((pstartpos == NULL || pendpos == NULL) ||
       pstartpos->direction == pendpos->direction)
        return false;

    m_SwitchStateMounts[(SwitchState)state] = SwitchStateMounts(pstartpos,pendpos);

    return true;
}

/// 工作区域改变
void WSwitchNode::changeWorkingRect(wxRect workingrect)
{
    WBaseNode::changeWorkingRect(workingrect);

    // 计算实际显示点
    mScreenCenterPosition = wxRealPoint(workingrect.GetLeftTop().x+workingrect.GetWidth()*(mCenterPosition.x/100.0f),
                              workingrect.GetLeftTop().y+workingrect.GetHeight()*(mCenterPosition.y/100.0f));

    int tmpSize = IDD_SWITCHRECT_SIZE/2;

    // 计算包围盒
    wxPoint points[4];
    points[0] = wxPoint(mScreenCenterPosition.x-tmpSize,mScreenCenterPosition.y-tmpSize);
    points[1] = wxPoint(mScreenCenterPosition.x+tmpSize,mScreenCenterPosition.y-tmpSize);
    points[2] = wxPoint(mScreenCenterPosition.x+tmpSize,mScreenCenterPosition.y+tmpSize);
    points[3] = wxPoint(mScreenCenterPosition.x-tmpSize,mScreenCenterPosition.y+tmpSize);

    this->setBoundingRect(wxPolygonEx(4,points));
}

/// 更新
void WSwitchNode::update(void)
{
    if(m_onUpdateEventString == "")
        return;

    // 调用lua更新脚本接口
    ScriptManager::getSingleton().callLuaFunctionWithBaseNodeUpdate(m_onUpdateEventString.ToUTF8().data());
}

/// 绘制内部路线
void WSwitchNode::drawRoute(maindrawscene *painter)
{
    std::map<SwitchState,SwitchStateMounts>::iterator iter = m_SwitchStateMounts.find(m_SwitchState);
    if(iter == m_SwitchStateMounts.end())
        return;

    tagMountPoint* pstartpos = (*iter).second.startMount;
    tagMountPoint* pendpos = (*iter).second.endMount;
    wxColour decColour = this->getColourByState();

    if(pstartpos && pendpos)
    {
        wxPoint centerPoint = this->getScreenPosition();
        wxRealPoint pstartPoint = pstartpos->screenpos;
        wxRealPoint pendPoint = pendpos->screenpos;

        painter->DrawLine(pstartPoint,centerPoint,2.0f,decColour);
        painter->DrawLine(centerPoint,pendPoint,2.0f,decColour);
    }
}

/// 绘制
void WSwitchNode::draw(maindrawscene *painter)
{
    // 绘制结点名称
    painter->DrawText1(this->getName().ToUTF8().data(),
                       wxRealPoint(this->getScreenPosition().x,
                               this->getScreenPosition().y-IDD_SWITCHRECT_SIZE-5),
                       1.0f,
                       this->getTextColourByState());

    // 绘制包围盒
    this->DrawBoundingBox(painter);

    // 绘制挂载点
    this->DrawMountPoints(painter);

    // 绘制内部路线
    this->drawRoute(painter);

    if(m_onDrawEventString != "")
    {
        // 调用lua绘制脚本接口
        ScriptManager::getSingleton().callLuaFunctionWithBaseNodeDraw(painter,m_onDrawEventString.ToUTF8().data());
    }
}

/// 处理鼠标事件
bool WSwitchNode::OnMMouseEvent(wxMouseEvent event)
{
    if(m_onMouseEventString == "")
        return false;

    /// 调用结点的鼠标事件接口
    ScriptManager::getSingleton().callLuaFunctionWithBaseNodeMouseEvent(m_onMouseEventString.ToUTF8().data(),
                                                                        event);

    return false;
}
